"""
ConnLLM Moonshot工具调用能力V2实现
提供Moonshot API工具调用功能
"""

from typing import Dict, Any, List, Optional, Callable, Union
import json
import logging
import uuid
import inspect

from ...core_v2.capability import ModelCapability

logger = logging.getLogger("connllm.implementations.moonshot.tool_call_v2")

class MoonshotToolCallV2(ModelCapability):
	"""Moonshot工具调用能力V2实现"""
	
	def __init__(self, provider):
		"""
		初始化能力
		
		Args:
			provider: 提供商实例
		"""
		super().__init__(provider)
		self.tools = {}  # 存储注册的工具
	
	def register_tool(self, name: str, description: str, 
					 parameters: Dict[str, Any], 
					 function: Callable) -> None:
		"""
		注册工具
		
		Args:
			name: 工具名称
			description: 工具描述
			parameters: 工具参数
			function: 工具函数
		"""
		# 创建工具定义
		tool_def = {
			"type": "function",
			"function": {
				"name": name,
				"description": description,
				"parameters": parameters
			}
		}
		
		# 添加到工具字典
		self.tools[name] = {
			"definition": tool_def,
			"function": function
		}
		
		logger.debug(f"已注册工具: {name}")
	
	def prepare_request(self, params: Dict[str, Any]) -> Dict[str, Any]:
		"""
		准备请求参数，添加工具定义
		
		Args:
			params: 请求参数
			
		Returns:
			处理后的请求参数
		"""
		# 如果没有注册工具，直接返回
		if not self.tools:
			return params
		
		# 从配置或上下文中获取工具设置
		tools_config = self.provider.config_manager.get("tools", {})
		
		# 如果显式禁用工具，直接返回
		if tools_config.get("enabled", True) is False:
			return params
		
		# 创建工具定义列表
		tools = []
		for name, tool_info in self.tools.items():
			tools.append(tool_info["definition"])
		
		# 添加工具定义到参数
		if tools:
			params["tools"] = tools
			
			# 如果未设置tool_choice，默认为auto
			if "tool_choice" not in params:
				params["tool_choice"] = "auto"
		
		return params
	
	def detect_tool_calls(self, response: Dict[str, Any]) -> List[Dict[str, Any]]:
		"""
		从响应中检测工具调用
		
		Args:
			response: API响应
			
		Returns:
			检测到的工具调用列表
		"""
		tool_calls = []
		
		try:
			# 检查响应中是否有工具调用
			if "choices" in response and len(response["choices"]) > 0:
				choice = response["choices"][0]
				
				if "message" in choice and "tool_calls" in choice["message"]:
					raw_tool_calls = choice["message"]["tool_calls"]
					
					# 处理每个工具调用
					for tool_call in raw_tool_calls:
						# 确保是函数调用
						if tool_call.get("type") == "function":
							function = tool_call.get("function", {})
							
							# 提取工具调用信息
							call_info = {
								"id": tool_call.get("id", str(uuid.uuid4())),
								"name": function.get("name", ""),
								"arguments": function.get("arguments", "{}")
							}
							
							# 如果arguments是字符串，尝试解析为JSON
							if isinstance(call_info["arguments"], str):
								try:
									call_info["arguments"] = json.loads(call_info["arguments"])
								except json.JSONDecodeError:
									logger.warning(f"解析工具参数失败: {call_info['arguments']}")
									call_info["arguments"] = {}
							
							tool_calls.append(call_info)
		except Exception as e:
			logger.error(f"检测工具调用失败: {str(e)}")
		
		return tool_calls
	
	def execute_tool_calls(self, tool_calls: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
		"""
		执行工具调用
		
		Args:
			tool_calls: 工具调用列表
			
		Returns:
			工具结果消息列表
		"""
		tool_results = []
		
		for call in tool_calls:
			tool_name = call.get("name", "")
			tool_id = call.get("id", "")
			arguments = call.get("arguments", {})
			
			# 检查工具是否存在
			if tool_name not in self.tools:
				logger.warning(f"未知工具: {tool_name}")
				result = {"error": f"未知工具: {tool_name}"}
			else:
				# 执行工具函数
				try:
					func = self.tools[tool_name]["function"]
					
					# 检查函数是否接受关键字参数
					if inspect.signature(func).parameters:
						result = func(**arguments)
					else:
						result = func()
				except Exception as e:
					logger.error(f"执行工具失败: {str(e)}")
					result = {"error": f"执行错误: {str(e)}"}
			
			# 创建工具结果消息
			content = json.dumps(result, ensure_ascii=False) if isinstance(result, (dict, list)) else str(result)
			
			tool_result = {
				"role": "tool",
				"tool_call_id": tool_id,
				"name": tool_name,
				"content": content
			}
			
			tool_results.append(tool_result)
		
		return tool_results
